home *** CD-ROM | disk | FTP | other *** search
- ;****************************************************************************
- ; FILEMON monitors the system file table as an aid in determining the
- ; optimal setting for FILES= in CONFIG.SYS. Its syntax is:
- ;
- ; FILEMON
- ;
- ; The first time it's run, FILEMON becomes memory-resident so it can track
- ; file activity in the background. Each time thereafter, it reports the
- ; number of files that are currently open and the maximum that were open
- ; at any time since monitoring was begun.
- ;****************************************************************************
-
- code segment
- assume cs:code
- org 100h
- begin: jmp init
-
- signature db 0,1,2,"FILEMON",2,1,0 ;Program signature
- prog_id db ? ;Multiplex ID number
- int21h dd ? ;Interrupt 21h vector
- int2Fh dd ? ;Interrupt 2FH vector
- maxfiles db 0 ;Maximum file open count
- lol dd ? ;List of Lists address
-
- ;****************************************************************************
- ; DOS_INT handles calls to interrupt 21h.
- ;****************************************************************************
-
- dos_int proc far
- pushf ;Save FLAGS
- cmp ah,3Ch ;Create file?
- je dosint1
- cmp ah,3Dh ;Open file?
- je dosint1
- cmp ah,45h ;Duplicate handle?
- je dosint1
- cmp ah,46h ;Force duplicate handle?
- je dosint1
- cmp ah,5Ah ;Create temporary file?
- je dosint1
- cmp ah,5Bh ;Create new file?
- je dosint1
- cmp ah,6Ch ;Extended open/create?
- je dosint1
- popf ;Restore FLAGS
- jmp cs:[int21h] ;Jump to DOS
- ;
- ; Place the call to DOS, then count the number of open files upon return.
- ;
- dosint1: popf ;Restore FLAGS and call DOS
- pushf
- call cs:[int21h]
-
- pushf ;Save registers
- push ax
- push cx
- push si
- push di
- push es
-
- sti ;Interrupts on
- call count_files ;Count open files
- cmp al,cs:[maxfiles] ;Record result if count
- jbe dosint2 ;exceeds current maximum
- mov cs:[maxfiles],al
-
- dosint2: pop es ;Restore registers
- pop di
- pop si
- pop cx
- pop ax
- popf
- sti ;Enable interrupts
- ret 2 ;Exit with FLAGS intact
- dos_int endp
-
- ;****************************************************************************
- ; MPLEX_INT handles interrupt 2FH. If, on entry, AH is set to INSTALL's
- ; multiplex ID number, MPLEX_INT uses the value in AL as a function code.
- ; The functions supported are:
- ;
- ; 00H Returns FFH in AL to indicate the program is installed
- ; and returns the address of its signature in ES:DI.
- ;
- ; 01H Returns the number of files currently open in AL and the
- ; maximum number of files open concurrently in AH.
- ;****************************************************************************
-
- mplex_int proc far
- pushf ;Save FLAGS register
- cmp ah,cs:[prog_id] ;Branch if AH holds the
- je mplex2 ;multiplex ID
- popf ;Restore FLAGS
- jmp cs:[int2Fh] ;Pass the interrupt on
- ;
- ; Function 00H verifies that the program is installed.
- ;
- mplex2: popf ;Restore FLAGS
- or al,al ;Branch if function code
- jnz mplex3 ;is other than 00h
- mov al,0FFh ;Set AL to FFh
- push cs ;Point ES:DI to the program
- pop es ;signature
- mov di,offset signature
- ;
- ; Function 01H returns the number of open files (current and maximum).
- ;
- mplex3: cmp al,1 ;Exit if function code
- jne mplex5 ;is other than 01h
- call count_files ;Count open files
- cmp al,cs:[maxfiles] ;Record result if count
- jbe mplex4 ;exceeds current maximum
- mov cs:[maxfiles],al
- mplex4: mov ah,cs:[maxfiles] ;Load AH with maximum count
- mplex5: iret ;Return from interrupt
- mplex_int endp
-
- ;****************************************************************************
- ; COUNT_FILES returns in AL the number of files that are currently open.
- ;****************************************************************************
-
- count_files proc near
- les di,cs:[lol] ;Get List of Lists address
- les di,es:[di+4] ;Get address of SFT
- xor al,al ;Zero file count
-
- countf1: mov cx,es:[di+4] ;Get count of SFT entries
- jcxz countf4 ;Branch if count is zero
- mov si,di ;Point SI to the first SFT
- add si,6 ;entry in this block
-
- countf2: cmp word ptr es:[si],0 ;Increment count in AL if
- je countf3 ;the handle count is not
- inc al ;zero
- countf3: add si,59 ;Point SI to the next entry
- loop countf2 ;Loop until all entries done
-
- countf4: cmp word ptr es:[di],0FFFFh ;Exit if this is the last
- je cf_exit ;block in the chain
- les di,es:[di] ;Get address of next block
- jmp countf1 ;Reenter the loop
- cf_exit: ret
- count_files endp
-
- ;****************************************************************************
- ; Data that will be discarded when the program becomes memory-resident.
- ;****************************************************************************
-
- helpmsg db "Tracks file activity as an aid in determining the "
- db "optimum setting for the",13,10
- db "FILES= statement in CONFIG.SYS.",13,10,"$"
-
- errmsg1 db "Requires DOS 5 or DOS 6",13,10,"$"
- errmsg2 db "Program could not be installed"
- crlf db 13,10,"$"
-
- copyright db "FILEMON 1.1 Copyright (c) 1993 Jeff Prosise",13,10
- db "From: PC Magazine DOS 6 Memory Management "
- db "with Utilities",13,10,13,10,"$"
-
- msg1 db "Program installed. Type FILEMON to determine the "
- db "number of open files.",13,10,"$"
- msg2 db "Files currently open: $"
- msg3 db "Maximum thus far: $"
-
- ;****************************************************************************
- ; INIT makes the program resident in memory.
- ;****************************************************************************
-
- assume cs:code,ds:code
-
- init proc near
- cld ;Clear direction flag
- mov si,81h ;Point SI to command line
- call scanhelp ;Scan for "/?" switch
- jnc init1 ;Branch if not found
- mov ah,09h ;Display help text and exit
- mov dx,offset helpmsg ;with ERRORLEVEL=0
- int 21h
- mov ax,4C00h
- int 21h
- ;
- ; Check the DOS version.
- ;
- init1: mov dx,offset errmsg1 ;Error if DOS version
- mov ah,30h ;is not 5 or 6
- int 21h
- cmp al,5
- je init2
- cmp al,6
- je init2
-
- error: mov ah,09h ;Display error message and
- int 21h ;exit with ERRORLEVEL=1
- mov ax,4C01h
- int 21h
- ;
- ; Display file status is program is already installed.
- ;
- init2: call check_install ;Branch if the program is
- jnc install ;not installed
-
- push ax
- mov ah,09h ;Display copyright message
- mov dx,offset copyright
- int 21h
- pop ax
-
- mov al,01h ;Get file statistics
- int 2Fh
- mov bx,ax ;Transfer the result to BX
-
- mov ah,09h ;Display the number of files
- mov dx,offset msg2 ;currently open
- int 21h
- mov al,bl
- xor ah,ah
- call bin2asc
-
- mov ah,09h ;Display the maximum file
- mov dx,offset msg3 ;count
- int 21h
- mov al,bh
- xor ah,ah
- call bin2asc
-
- mov ax,4C00h ;Exit with ERRORLEVEL=0
- int 21h
- ;
- ; Install the program.
- ;
- install: call mplex_id ;Find a multiplex ID number
- mov dx,offset errmsg2 ;Error if none available
- jc error
- mov prog_id,ah ;Save the ID number
-
- mov ax,3521h ;Hook interrupt 21H
- int 21h
- mov word ptr int21h,bx
- mov word ptr int21h[2],es
- mov ax,2521h
- mov dx,offset dos_int
- int 21h
-
- mov ax,352Fh ;Hook interrupt 2FH
- int 21h
- mov word ptr int2Fh,bx
- mov word ptr int2Fh[2],es
- mov ax,252Fh
- mov dx,offset mplex_int
- int 21h
-
- mov ah,49h ;Free the local block
- mov es,ds:[2Ch] ;environment block
- int 21h
-
- mov ah,52h ;Get and save the address
- int 21h ;of the List of Lists
- mov word ptr lol,bx
- mov word ptr lol[2],es
-
- mov ah,09h ;Display message verifying
- mov dx,offset copyright ;the installation
- int 21h
- mov ah,09h
- mov dx,offset msg1
- int 21h
-
- mov ax,3100h ;Terminate with function 31H
- mov dx,(offset helpmsg - offset code + 15) shr 4
- int 21h
- init endp
-
- ;****************************************************************************
- ; SCANHELP scans the command line for a /? switch. If found, carry returns
- ; set and SI contains its offset. If not found, carry returns clear.
- ;****************************************************************************
-
- scanhelp proc near
- push si ;Save SI
- scanloop: lodsb ;Get a character
- cmp al,0Dh ;Exit if end of line
- je scan_exit
- cmp al,"?" ;Loop if not "?"
- jne scanloop
- cmp byte ptr [si-2],"/" ;Loop if not "/"
- jne scanloop
-
- add sp,2 ;Clear the stack
- sub si,2 ;Adjust SI
- stc ;Set carry and exit
- ret
-
- scan_exit: pop si ;Restore SI
- clc ;Clear carry and exit
- ret
- scanhelp endp
-
- ;****************************************************************************
- ; CHECK_INSTALL returns carry set if the program is already installed,
- ; carry clear if it's not. If carry returns set, AH holds the program's
- ; multiplex ID number.
- ;****************************************************************************
-
- check_install proc near
- mov ax,0C000h ;Initialize AH and AL
- mov cx,40h ;Initialize count
-
- chinst1: push ax ;Save AX and CX
- push cx
- sub di,di ;Set ES and DI to 0
- mov es,di
- int 2Fh ;Interrupt 2Fh
- cmp al,0FFh ;Nothing here if AL isn't
- jne chinst2 ;equal to FFH
-
- mov si,offset signature ;See if program signature
- mov cx,13 ;appears at the address
- repe cmpsb ;returned in ES:DI
- jne chinst2 ;Branch if it does not
-
- pop cx ;Clear the stack and exit
- pop ax ;with carry set
- stc
- ret
-
- chinst2: pop cx ;Retrieve AX and CX
- pop ax
- inc ah ;Next multiplex ID
- loop chinst1 ;Loop until done
-
- clc ;Exit with carry clear
- ret
- check_install endp
-
- ;****************************************************************************
- ; MPLEX_ID searches for an unused multiplex ID number. If one is found,
- ; it is returned in AH with carry clear. Carry set means no multiplex
- ; ID numbers are currently available.
- ;****************************************************************************
-
- mplex_id proc near
- mov ax,0C000h ;Initialize AH and AL
- mov cx,40h ;Initialize count
-
- mxid1: push ax ;Save AX and CX
- push cx
- int 2Fh ;Interrupt 2Fh
- or al,al ;Branch if AL=0
- jz mxid2
- pop cx ;Retrieve AX and CX
- pop ax
- inc ah ;Increment ID number
- loop mxid1 ;Loop until done
-
- stc ;Exit with carry set
- ret
-
- mxid2: pop cx ;Clear the stack and exit
- pop ax ;with carry clear
- clc
- ret
- mplex_id endp
-
- ;****************************************************************************
- ; BIN2ASC converts a binary value in AX to ASCII form and displays it.
- ;****************************************************************************
-
- ten dw 10 ;Base 10 divisor
-
- bin2asc proc near
- xor cx,cx ;Initialize digit counter
- b2a1: inc cx ;Increment digit count
- xor dx,dx ;Divide by 10
- div ten
- push dx ;Save remainder on stack
- or ax,ax ;Loop until quotient is zero
- jnz b2a1
- b2a2: pop dx ;Retrieve a digit from stack
- add dl,30h ;Convert it to ASCII
- mov ah,2 ;Display it
- int 21h
- loop b2a2 ;Loop until done
- mov ah,09h ;Move the cursor to the
- mov dx,offset crlf ;next line
- int 21h
- ret
- bin2asc endp
-
- code ends
- end begin
-